<?xml version="1.0" encoding="UTF-8"?>
<html>
    <head>
        <link type="text/css" rel="stylesheet" href="./css/template.css" />
        <link type="text/css" rel="stylesheet" href="./css/SyntaxHighlighter.css" />
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>Le VRML en Java - Articles - 1/7 - Java &amp; Solaris par le Laboratoire SUPINFO des technologies Sun </title>
        <script language="javascript" src="./js/shInit.js" />
        <script language="javascript" src="./js/shCore.js" />
        <script language="javascript" src="./js/shBrushCpp.js" />
        <script language="javascript" src="./js/shBrushCSharp.js" />
        <script language="javascript" src="./js/shBrushCss.js" />
        <script language="javascript" src="./js/shBrushDelphi.js" />
        <script language="javascript" src="./js/shBrushJava.js" />
        <script language="javascript" src="./js/shBrushJScript.js" />
        <script language="javascript" src="./js/shBrushPhp.js" />
        <script language="javascript" src="./js/shBrushPython.js" />
        <script language="javascript" src="./js/shBrushRuby.js" />
        <script language="javascript" src="./js/shBrushSql.js" />
        <script language="javascript" src="./js/shBrushVb.js" />
        <script language="javascript" src="./js/shBrushXml.js" />
        <keywords>html,3D,tridimensionnel,Java,GUI,Web,le,vrml,en,java,articles,1,7,certification,sun,java,solaris,articles,essentiels,tips,astuces,codes,exemple,tutorial,developpement,jsp,servlet,jdbc,jdo,j2se,j2ee,laboratoire</keywords>
        <author>Félix Dewaleyne</author>
    </head>
    <body>
        <div class="chapter">
            <h2>Introduction</h2>
            <div class="subChapter">
                <h3>Qu'est ce que le VRML ?</h3>
                <p>Le VRML est apparu en 1995 dans le but de permettre l'affichage tridimensionnel sur le net.</p>
                <p>Cependant la dernière version, la 2.0, est sortie en 1997 et devait laisser place à une nouvelle version en 2000... qui n'est pas parue.</p>
                <p>Le VRML est un langage dont la syntaxe est comparable à celle du Java. Comparé aux autres, qui utilisent majoritairement des systèmes de balises, ceci constitue un grand avantage.</p>
                <p>
                    Pour afficher la scène vous aurez besoin d'un plugin :
                    <a href="http://www.parallelgraphics.com/products/cortona/" target="_about">le client Cortona (http://www.parallelgraphics.com/products/cortona/)</a>
                </p>
                <p>
                    Voici un exemple de code VRML et
                    <a href="http://www.labo-sun.com/data/resources/632/files/01.wrl" target="_about">un lien vers la scène en 3D qu'il représente</a>
                </p>
                <textarea name="code" class="vb">#VRML V2.0
					#Une boîte en rotation autour de y
					Transform {
					#Déclaration de l'objet fils
					children Shape {
					#Création de la forme de la boïte
					geometry Box {
					}
					}
					#Paramètre x, y, z de la translation
					translation 0 0 -2
					#Paramètre x,y,z et a de la rotation
					rotation 0 1 0 0.79
					}</textarea>
                <p>
                    <em>Cette scène est constituée d'une boite placée à 2 cm vers l'arrière et qui subit une rotation de 45° (soit 0,79 radians) sur l'axe y).</em>
                </p>
                <p>Il permet d'afficher d’afficher et de gérer une scène en 3D : tout ce qu'il faut définir dans le code n'est que formes et textures à utiliser.. voire même musique d'ambiance ou effet sonore.</p>
                <p>Le VRML est un langage qui n'existe que pour représenter la 3D sur le web et il reste un langage de description qui n'a jamais besoin d'être compilé pour être utilisé, ce qui lui donne toute sa légèreté d'utilisation.</p>
            </div>
            <div class="subChapter">
                <h3>Pourquoi l'utiliser ?</h3>
                <p>Ce langage est reconnu par beaucoup de programmes de création 3D (dont 3D Studio MAX), même si ceux-ci ont tendance à générer trop de code. Il permet de générer une scène qui sera affichée partout de la même façon (sous réserve de disponibilité des éléments externes).</p>
                <p>Grâce à sa syntaxe proche du Java, VRML peut facilement être utilisé pour créer des scènes complètes, complexes et interactives (grâce au Java et au programme de lecture), visionnables depuis un browser ou non (cela dépends du logiciel utilisé pour le lire).</p>
                <p>La notion de site web interactif en trois dimensions n’est pas négligeable mais cependant les problèmes non résolus par le VRML sont toujours un obstacle : la qualité des images ne dépend presque pas du langage mais de la façon dont il est lu et le traitement de scènes trop complexes prend trop de temps, ce qui est dû en grande partie dans le choix d’utiliser des éléments externes au plugin.</p>
            </div>
            <div class="subChapter">
                <h3>VRML et Java : quel lien ?</h3>
                <p>Le VRML est un langage qui ne peut que décrire des objets et presque pas leurs interactions : c'est à ces fins que le VRML utilisera le javascript.</p>
                <p>A ces fins il sera possible d'utiliser les Interfaces Java pour l'API VRML afin de générer et modifier des objets VRML mais aussi de gérer le navigateur grâce au Java.</p>
            </div>
        </div>
        <div class="chapter">
            <h2>VRML et Java :</h2>
            <p>Dans ce document vous trouverez tout ce qu'il vous faut savoir pour programmer une scène interactive.</p>
            <div class="subChapter">
                <h3>Bases</h3>
                <p>Pour programmer une scène interactive en utilisant du java il faudra utiliser le noeud Script. Ce noeud permet de recevoir des évènements qui indiquent des changements ou des actions des utilisateurs. Chaque noeud est associé à du code écrit. Ces scripts fonctionnent en deux parties et généralement pour transformer des champs : la partie VRML peut donner des champs d'entrée et de sortie dans lesquels le script va aller lire et écrire. Tous les types de champs peuvent être utilisés.</p>
                <p>Exemple :</p>
                <textarea name="code" class="vb">Script {
					#champs nécessaires
					url "http://toto.com/titi.class"
					scriptType "javabc"
					# enventIn type nom pour un événement  dans lequel le
					# script pourra écrire
					eventIn SFString nom
					eventIn SFBool select
					# eventOut type nom pour un événement lisible par
					# le script
					eventOut SFString ecriture
					field SFInt32 etatCourant 0
					field SFBool mustEvaluate TRUE
					}</textarea>
                <p>Voici en détail tous les champs du noeud Script (avec leurs valeurs par défaut) :</p>
                <textarea name="code" class="vb">Script {
					field MFString url []
					# contient l'url du script à utiliser
					field SFString scriptType ""
					# contient le type de script à utiliser
					# (généralement javabc)
					field SFBool mustEvaluate FALSE
					# par défaut, le script n'est utilisé quen cas de besoin
					# absolu (valeur FALSE)
					# Si on a TRUE, on force l'envoi d'évènements au script.
					# Ce champ ne doit être mis à TRUE que si le script a
					# des effets inconnus sur le navigateur
					# (par exemple l'envoi d'informations sur le réseau)
					field SFBool directOutputs FALSE
					# restreint l'accès au monde au script si FALSE en
					# l'obligeant à passer par les évènements de sortie.
					# si la valeur est TRUE, le script peut envoyer des
					# évènements dans tous les noeuds où il a accès et
					# peut dynamiquement créer et détruire des routes.
					# autant de fois que nécessaire :
					enevtIn nomTypeEvenement nomEvenement
					field nomTypeChamp nomChamp
					eventOut nomTypeChamp nomEvenement
					}</textarea>
                <p>Du côté du javascript, il faut utiliser les classes et méthodes définies ci-dessous (pour un exemple, voir en fin de page).</p>
            </div>
            <div class="subChapter">
                <h3>Classes et méthodes exposées pour les noeuds et les champs :</h3>
                <p>Ces classes sont toutes définies dans un paquetage nommé vrml.</p>
                <p>La classe Field hérite de la classe Java Object par défaut (comme lorsqu'elle est déclarée sans classe supérieure comme ici).</p>
                <p>Le reste du paquetage définit une classe Const en lecture pour chaque type de champ VRML et une méthode getValue() pour chaque classe et une autre classe en lecture/écriture pour chaque type de champ VRML ainsi que les méthodes getValue() et SetValue() pour chaque classe.</p>
                <p>La plupart des méthodes setValue() sont décrites comme throws exceptions, ce qui peut vous amener à utiliser un gestionnaire d'exception. On garantit que chaque méthode décrite sans throws exceptions ne peut pas en générer. De plus, chacune des méthodes commentées de cette manière l'est également sur le type d'exception qu'elle générera.</p>
                <textarea name="code" class="java">package vrml;
					class Field {
					}
					// classes seulement en lecture (constante), une pour
					//chaque type de champ:
					class ConstSFBool extends Field {
					public boolean getValue()
					}
					class ConstSFColor extends Field {
					public float[] getValue();
					}
					class ConstMFColor extends Field {
					public float[][] getValue();
					}
					class ConstSFFloat extends Field {
					public float getValue();
					}
					class ConstMFFloat extends Field {
					public float[] getValue();
					}
					class ConstSFImage extends Field {
					public byte[] getValue(int[] dims);
					}
					class ConstSFInt32 extends Field {
					public int getValue();
					}
					class ConstMFInt32 extends Field {
					public int[] getValue();
					}
					class ConstSFNode extends Field {
					public Node getValue();
					}
					class ConstMFNode extends Field {
					public Node[] getValue();
					}
					class ConstSFRotation extends Field {
					public float[] getValue();
					}
					class ConstMFRotation extends Field {
					public float[][] getValue();
					}
					class ConstSFString extends Field {
					public String getValue();
					}
					class ConstMFString extends Field {
					public String[] getValue();
					}
					class ConstSFVec2f extends Field {
					public float[] getValue();
					}
					class ConstMFVec2f extends Field {
					public float[][] getValue();
					}
					class ConstSFVec3f extends Field {
					public float[] getValue();
					}
					class ConstMFVec3f extends Field {
					public float[][] getValue();
					}
					class ConstSFTime extends Field {
					public double getValue();
					}
					// Et maintenant les versions modifiables des classes
					//précédentes :
					class SFVec2f extends Field {
					public float[] getValue();
					public void setValue(float[] value)
					throws ArrayIndexOutOfBoundsException;
					}
					class SFVec3f extends Field {
					public float[] getValue();
					public void setValue(float[] value)
					throws ArraylndexOutOfBoundsException;
					}
					class MFVec2f extends Field {
					public float[][] getValue();
					public void setValue(float[][] value)
					throws ArrayIndexOutOfBoundsException;
					public void setValue(ConstMFVec2f value);
					public void set1Value(int index, float[] value);
					}
					class MFVec3f extends Field {
					public float[][] getValue();
					public void setValue(float[][] value)
					throws ArrayIndexOutOfBoundsException;
					public void setValue(ConstMFVec3f value);
					public void set1Value(int index, float[] value);
					}
					// Interfaces (classes abstraites dont vos classes peuvent
					// hériter mais que vous ne
					// pouvez pas instancier) relatives aux événements
					// et aux noeuds :
					interface EventIn {
					public String getName();
					public SFTime getTimeStamp();
					public ConstField getValue();
					}
					interface Node {
					public ConstField getValue(String fieldName)
					throws InvalidFieldException;
					public void postEventln(String eventName,
					Field eventValue)
					throws InvalideEventlnException;
					}
					// Ceci est la classe générale Script, elle doit être
					// dérivée par tous les scripts. Notez que la
					// méthode fournie permet à l'auteur du script de
					// générer de façon explicite des exceptions adaptées
					// au cas où quelque chose allait mal dans le script;
					// le code d'exception pour ces exceptions doit donc
					// être déterminé par l'auteur du script
					class Script implements Node {
					// Script:code is up to script author
					public void processEvents(Events [] events)
					throws Exception;
					// Script: code is up to script author
					public void eventsProcessed()
					throws Exception;
					protected Field getEventOut(String eventName)
					throws InvalidEventOutException;
					protected Field getField(String fieldName)
					throws InvalidFieldException;
					}</textarea>
            </div>
            <div class="subChapter">
                <h3>Interface avec le navigateur</h3>
                <p>Voici une liste des interfaces publiques Java vers la classe Browser qui permettent aux scripts de lire et d'écrire des informations du navigateur.</p>
                <textarea name="code" class="java">public static String getName();
					public static String getVersion();
					public static String getNavigationType();
					public static void setNavigationType(String type)
					throws InvaIidNavigationTypeException;
					public static float getNavigationSpeed();
					public static void setNavigationSpeed(float speed);
					public static float getCurrentSpeed();
					public static float getNavigationScale();
					public static void setNavigationScale(float scale);
					public static boolean getHeadlight();
					public static void setHeadlight(boolean onOff);
					public static String getWorldURL();
					public static void loadWorld(String [] uri);
					public static float getCurrentFrameRate();
					public static Node createVrmlFromURL (String[] uri)
					throws InvalidVRMLException;
					public static Node createVrmlFromString (String vrmlSyntax)
					throws InvalidVRMLException;
					public void addRoute (Node fromNode, String fromEventOut,
					Node toNode, String toEventln)
					throws InvalidRouteException;
					public void deleteRoute (Node fromNode, String fromEventOut,
					Node toNode, String toEventln)
					throws InvalidRouteException;
					public void bindBackground(Node background);
					public void unbindBackground();
					public boolean isBackgroundBound(Node background);
					public void bindNavigationlnfo(Node navigationlnfo);
					public void unbindNavigationlnfo();
					public boolean isNavigationlnfoBound(Node navigationlnfo);
					public void bindViewpoint(Node viewpoint);
					public void unbindViewpoint();
					public boolean isViewpointBound(Node viewpoint);</textarea>
            </div>
            <div class="subChapter">
                <h3>Bibliothèques système et d'interface réseau</h3>
                <p>Si, pendant une scène, il faut appeler le système ou le réseau, on devra alors faire appel aux bibliothèques Java standards.</p>
                <p>Par exemple :</p>
                <p>Dans cet exemple nous étudierons un script qui dira si une couleur est rouge.</p>
                <textarea name="code" class="vb">Script {
					field SFColor couleurActuelle 0 0 0
					eventIn SFColor couleurIn
					eventOut SFBool estRouge
					scriptType "javabc"
					behavior "ScriptExemple.java"
					}</textarea>
                <p>Après avoir vu le code VRML du noeud Script</p>
                <textarea name="code" class="java">class ScriptExemple extends Script {
					//Déclaration du(des) champ(s)
					private SFColor couleurActuelle = (SFColor) getField("couleurActuelle");
					//Déclaration du(des) champ(s) enevtOut
					private SFBool estRouge = (SFBool) getEventOut("estRouge");
					public void eventsProcessed() {
					if(couleurActuelle.getValue()[0] &gt;= 0.5)
					//si le rouge est présent à au moins 50%
					estRouge.setValue(TRUE);
					}
					}</textarea>
            </div>
        </div>
    </body>
</html>

